package com.jungle.mediaplayer.manager;

import android.annotation.TargetApi;
import android.content.Context;
import android.media.AudioAttributes;
import android.media.AudioFocusRequest;
import android.media.AudioManager;
import android.os.Build;
import android.util.Log;

import com.jungle.mediaplayer.base.BaseMediaPlayerListener;
import com.jungle.mediaplayer.base.VideoInfo;
import com.jungle.mediaplayer.player.BaseMediaPlayer;
import com.jungle.mediaplayer.player.SystemImplMediaPlayer;

import java.util.ArrayList;
import java.util.List;

@TargetApi(Build.VERSION_CODES.O)
public class MediaManager {
    private final String TAG = "launcherMediaManager";
    private Context mContext;
    private static MediaManager mInstance;

    private List<VideoInfo> videoInfoList = new ArrayList<>();
    private int index = 0;//当前正在播放的列表

    private BaseMediaPlayer mMediaPlayer;
    private AudioManager mAudioManager;

    private AudioAttributes mPlaybackAttributes;
    private AudioFocusRequest mFocusRequest;
    final Object mFocusLock = new Object();
    boolean mPlaybackDelayed = false;//延迟播放
    private boolean mResumeOnFocusGain = false;//在FocusGain状态是否调用resume重播
    public boolean isMediaPlaying = false;//音频是否正在播放
    private boolean commandMediaPause = false;//是否下达暂停命令

    public void setCommandMediaPause(boolean commandMediaPause) {
        this.commandMediaPause = commandMediaPause;
    }

    public boolean isMediaPlaying() {
        return isMediaPlaying;
    }

    private AudioManager.OnAudioFocusChangeListener mAudioFocusChangeListener = new AudioManager.OnAudioFocusChangeListener() {
        @Override
        public void onAudioFocusChange(int focusChange) {
            switch (focusChange) {
                case AudioManager.AUDIOFOCUS_GAIN:
                    Log.d(TAG, "AUDIOFOCUS_GAIN");
                    //当其他应用申请焦点之后又释放焦点会触发此回调
                    //可重新播放音乐
                    if (mPlaybackDelayed || mResumeOnFocusGain) {
                        synchronized (mFocusLock) {
                            mPlaybackDelayed = false;
                            mResumeOnFocusGain = false;
                        }
                        //恢复音量
                        mMediaPlayer.setVolume(1.0f);
                        if (isMediaPlaying && !commandMediaPause) {
                            resume();
                        }
                    }
                    break;
                case AudioManager.AUDIOFOCUS_LOSS:
                    Log.d(TAG, "AUDIOFOCUS_LOSS");
                    //长时间丢失焦点,当其他应用申请的焦点为AUDIOFOCUS_GAIN时，
                    //会触发此回调事件，例如播放QQ音乐，网易云音乐等
                    //通常需要暂停音乐播放，若没有暂停播放就会出现和其他音乐同时输出声音
                    synchronized (mFocusLock) {
                        mResumeOnFocusGain = false;
                        mPlaybackDelayed = false;
                    }
                    stop();
                    break;
                case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                    Log.d(TAG, "AUDIOFOCUS_LOSS_TRANSIENT");
                    //短暂性丢失焦点，当其他应用申请AUDIOFOCUS_GAIN_TRANSIENT时，
                    //会触发此回调事件，例如播放短视频，拨打电话等。
                    //通常需要暂停音乐播放
                    synchronized (mFocusLock) {
                        mResumeOnFocusGain = isPlaying();
                        mPlaybackDelayed = false;
                    }
                    if (isPlaying()) {
                        pause();
                    }
                case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
                    Log.d(TAG, "AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK");
                    //短暂性丢失焦点，当其他应用申请AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE时，
                    //会触发此回调事件，例如播放短视频，拨打电话等。
                    //短暂性丢失焦点并作降音处理
                    if (isPlaying()) {
                        mMediaPlayer.setVolume(0.1f);
                    }
                    break;
            }
        }
    };

    public static MediaManager getInstance(Context context) {
        if (mInstance == null) {
            synchronized (MediaManager.class) {
                if (mInstance == null) {
                    mInstance = new MediaManager(context);
                }
            }
        }
        return mInstance;
    }

    public MediaManager() {
        try {
            throw new Exception("MediaManager 不允许实例化");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private MediaManager(Context context) {
        init(context);
    }

    private void init(Context context) {
        this.mContext = context;
        mMediaPlayer = new SystemImplMediaPlayer(context);
        // 初始化音频属性和焦点请求
        mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);

        mPlaybackAttributes = new AudioAttributes.Builder()
                .setUsage(AudioAttributes.USAGE_MEDIA)
                .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
                .build();
        mFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
                .setAudioAttributes(mPlaybackAttributes)
                .setAcceptsDelayedFocusGain(true)
                .setWillPauseWhenDucked(true)
                .setOnAudioFocusChangeListener(mAudioFocusChangeListener)
                .build();
        mMediaPlayer.setAudioAttributes(mPlaybackAttributes);
        mMediaPlayer.addPlayerListener(new BaseMediaPlayerListener() {
            @Override
            public void onLoading() {

            }

            @Override
            public void onLoadFailed() {

            }

            @Override
            public void onFinishLoading() {

            }

            @Override
            public void onError(int what, boolean canReload, String message) {

            }

            @Override
            public void onStartPlay() {

            }

            @Override
            public void onPlayComplete() {
                playNext();
            }

            @Override
            public void onStartSeek() {

            }

            @Override
            public void onSeekComplete() {

            }

            @Override
            public void onResumed() {

            }

            @Override
            public void onPaused() {

            }

            @Override
            public void onStopped() {

            }
        });
    }

    /**
     * 说明：请求音频焦点
     */
    public void requestMediaFocus() {
        // 请求音频焦点
        int res = mAudioManager.requestAudioFocus(mFocusRequest);
        synchronized (mFocusLock) {
            if (res == AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
                mPlaybackDelayed = false;
            } else if (res == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
                mPlaybackDelayed = false;
                play();
            } else if (res == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) {
                mPlaybackDelayed = true;
            }
        }
    }

    public void setMediaList(List<? extends VideoInfo> list) {
        if (!list.isEmpty()) {
            this.videoInfoList.clear();
            this.videoInfoList.addAll(list);
        } else {
            try {
                throw new Exception("VideoInfoList为空！");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void addMediaList(VideoInfo info) {
        if (info != null) {
            this.videoInfoList.add(info);
        } else {
            try {
                throw new Exception("VideoInfo为空！");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public boolean isPlaying() {
        return mMediaPlayer.isPlaying();
    }

    public void play() {
        if (!videoInfoList.isEmpty()) {
            //请求音频焦点
//            requestMediaFocus();
            isMediaPlaying = true;
            mMediaPlayer.play(videoInfoList.get(index));
        } else {
            try {
                throw new Exception("VideoInfoList为空！请先添加媒体列表");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void playNext() {
        if (!videoInfoList.isEmpty()) {
            index++;
            if (index >= 0 && index < videoInfoList.size()) {
                //请求音频焦点
//                requestMediaFocus();
                isMediaPlaying = true;
                mMediaPlayer.play(videoInfoList.get(index));
            } else {
                index = 0;
                mMediaPlayer.play(videoInfoList.get(index));
            }
        } else {
            try {
                throw new Exception("VideoInfoList为空！请先添加媒体列表");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void playLast() {
        if (!videoInfoList.isEmpty()) {
            index--;
            if (index >= 0 && index < videoInfoList.size()) {
                //请求音频焦点
//                requestMediaFocus();
                isMediaPlaying = true;
                mMediaPlayer.play(videoInfoList.get(index));
            } else {
                index = videoInfoList.size() - 1;
                mMediaPlayer.play(videoInfoList.get(index));
            }
        } else {
            try {
                throw new Exception("VideoInfoList为空！请先添加媒体列表");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void pause() {
        mMediaPlayer.pause();
    }

    public void resume() {
        if (mMediaPlayer != null) {
            //请求音频焦点
//            requestMediaFocus();
            mMediaPlayer.resume();
        }
    }

    public void stop() {
        isMediaPlaying = false;
        //释放焦点，该方法可根据需要来决定是否调用
        //若焦点释放掉之后，将不会再自动获得
        mAudioManager.abandonAudioFocus(mAudioFocusChangeListener);

        mMediaPlayer.stop();
        mMediaPlayer.destroy();
    }

    public void replay() {
        if (isPlaying()) {
            isMediaPlaying = false;
            mMediaPlayer.stop();
            mMediaPlayer.destroy();
        }
        play();
    }

    public void addPlayerListener(BaseMediaPlayerListener listener) {
        mMediaPlayer.addPlayerListener(listener);
    }

    private void requestAudioFocus() {
        if (mAudioManager == null)
            mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
        if (mAudioManager != null) {
            Log.i(TAG, "Request audio focus");
            int ret = mAudioManager.requestAudioFocus(mAudioFocusChangeListener
                    , AudioManager.STREAM_MUSIC
                    , AudioManager.AUDIOFOCUS_GAIN);
            if (ret != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
                Log.i(TAG, "request audio focus fail. " + ret);
            }
        }
    }
}
